package com.dctp.common.utils;

import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

public class HolidayUtil {

    // 国家代码 -> ZoneId 映射
    private static final Map<String, ZoneId> COUNTRY_ZONE_MAP = Map.of(
            "CN", ZoneId.of("Asia/Shanghai"),
            "US", ZoneId.of("America/New_York"),
            "HK", ZoneId.of("Asia/Hong_Kong")
    );

    // 假期缓存（你可以从数据库加载）
    private static final Map<String, Set<LocalDate>> holidayMap = new HashMap<>();

    /**
     * 加载节假日数据（从数据库或其他来源）
     * @param country 国家代码
     * @param holidays 日期集合
     */
    public static void loadHolidays(String country, List<LocalDate> holidays) {
        holidayMap.put(country.toUpperCase(), new HashSet<>(holidays));
    }


    public static String getTodayLocalTime(String countryCode) {
        return DateUtil.format(LocalDateTime.now(COUNTRY_ZONE_MAP.get(countryCode)));
    }

    /**
     * 获取当前日期，按国家区分时区
     */
    public static LocalDate getToday(String country) {
        ZoneId zoneId = COUNTRY_ZONE_MAP.getOrDefault(country.toUpperCase(), ZoneId.systemDefault());
        return LocalDate.now(zoneId);
    }

    /**
     * 判断是否节假日
     */
    public static boolean isHoliday(String country, LocalDate date) {
        Set<LocalDate> holidays = holidayMap.getOrDefault(country.toUpperCase(), Collections.emptySet());
        return holidays.contains(date);
    }

    /**
     * 判断是否周末（星期六或星期日）
     */
    public static boolean isWeekend(LocalDate date) {
        DayOfWeek dow = date.getDayOfWeek();
        return dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY;
    }

    /**
     * 是否交易日（非节假日、非周末）
     */
    public static boolean isTradingDay(String country, ZonedDateTime now) {

        if (isHoliday(country,now.toLocalDate())) {
            return false;
        }

        boolean isWeekend = isWeekend(now.toLocalDate());

        LocalTime nowTime = now.toLocalTime();
        if (!isWeekend) {
            //判断是否小于美东时间17:00，小于则还在交易，加多1分钟，防止获取不到0分0秒的行情
            boolean before17Hour = nowTime.isBefore(LocalTime.of(17,1));
            if (before17Hour) {
                return true;
            }
            //查看是否在18点后，且明天是否是周末
            return nowTime.isAfter(LocalTime.of(18,0)) && !isWeekend(now.plusDays(1).toLocalDate());
        }

        //周末
        //判断是否是周日18:00,以美东时间为准
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        if ("US".equals(country)) {
            return dayOfWeek == DayOfWeek.SUNDAY && nowTime.isAfter(LocalTime.of(18,0));
        }else if ("HK".equals(country)) {
            //香港周六凌晨3点
            return dayOfWeek == DayOfWeek.SATURDAY && nowTime.isBefore(LocalTime.of(3,1));
        }
        return true;

    }


    /**
     * 根据国家代码返回对应的时区
     * @param countryCode 国家代码（如 CN、US、HK）
     * @return ZoneId 时区
     */
    public static ZoneId getZoneIdByCountry(String countryCode) {
        return COUNTRY_ZONE_MAP.getOrDefault(countryCode, ZoneId.systemDefault());
    }

    /**
     * 可选：从数据库查询并初始化所有节假日（建议放在启动时执行）
     */
    public static void initAllHolidaysFromDb() {
        // 示例：从数据库中查询
        // select holiday_date, country from dctp_holiday where year >= 2024
        List<Map<String, Object>> dbResult = fetchHolidaysFromDb();

        Map<String, List<LocalDate>> grouped = dbResult.stream()
                .collect(Collectors.groupingBy(
                        m -> ((String) m.get("country")).toUpperCase(),
                        Collectors.mapping(m -> ((Date) m.get("holiday_date")).toInstant()
                                .atZone(ZoneId.systemDefault()).toLocalDate(), Collectors.toList())
                ));

        for (Map.Entry<String, List<LocalDate>> entry : grouped.entrySet()) {
            loadHolidays(entry.getKey(), entry.getValue());
        }
    }

    // 示例：数据库查询接口（你要实现实际逻辑）
    private static List<Map<String, Object>> fetchHolidaysFromDb() {
        // 使用 Db.find(...) / JPA / MyBatis 等去查 holiday_date 和 country 字段
        return new ArrayList<>();
    }
}
